﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace TscMon
{
    class Notifier : ApplicationContext
    {
        const int NUMBER_LIMIT = 10;
        private Color OVERLAY_COLOR = Color.FromArgb(225, 215, 112, 15);
        private Color OVERLAY_DISABLED_COLOR = Color.FromArgb(225, 225, 40, 15);

        private TscProcessMon mon;
        private NotifyIcon notifier;

        private Icon[] icons;

        public Notifier()
        {
            InitIcons();
            InitNotifier();
            InitMonitor();

            RefreshNotifierState();
        }

        private void InitIcons()
        {
            icons = new Icon[NUMBER_LIMIT + 2];

            Icon baseIcon = TscMon.Properties.Resources.icon;

            int i = 0;
            icons[i++] = baseIcon;
            for (; i < NUMBER_LIMIT; i++) icons[i] = GenerateOverlayIcon(baseIcon, i.ToString(), OVERLAY_COLOR);
            icons[i++] = GenerateOverlayIcon(baseIcon, "+", OVERLAY_COLOR);
            icons[i++] = GenerateOverlayIcon(baseIcon, "", OVERLAY_DISABLED_COLOR);
        }

        private void InitNotifier()
        {
            notifier = new NotifyIcon();
            notifier.Icon = icons[0];
            notifier.Visible = true;

            notifier.ContextMenu = new ContextMenu(new MenuItem[] {
                new MenuItem("Enable", new EventHandler(Notifier_EnableClicked)),
                new MenuItem("Disable", new EventHandler(Notifier_DisableClicked)),
                new MenuItem("-"),
                new MenuItem("Exit", new EventHandler(Notifier_ExitClicked))
            });
        }

        private void InitMonitor()
        {
            mon = new TscProcessMon();
            mon.CountUpdated += Form1_CountUpdated;
        }

        private Icon GenerateOverlayIcon(Icon baseIcon, string overlay, Color color)
        {            
            Bitmap iconBitmap = new Bitmap(32, 32);
            Graphics canvas = Graphics.FromImage(iconBitmap);
            canvas.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;


            canvas.DrawIcon(baseIcon, 0, 0);

            StringFormat format = new StringFormat();
            format.Alignment = StringAlignment.Center;

            using (SolidBrush brush = new SolidBrush(color))
            {
                canvas.FillRectangle(
                    brush,
                    new RectangleF(0, 6, 32, 26)
                );
            }
            canvas.DrawString(
                overlay,
                new Font("Calibri", 18, FontStyle.Bold),
                Brushes.White,
                new RectangleF(0, 6, 32, 24),
                format
            );

            return Icon.FromHandle(iconBitmap.GetHicon());
        }

        void Form1_CountUpdated(object sender, TscProcessMon.CountUpdatedEventArgs e)
        {
            Update(e.NewCount);
        }

        void Notifier_EnableClicked(object sender, EventArgs e)
        {
            mon.Enable();
            Update(mon.Count);
            RefreshNotifierState();
        }

        void Notifier_DisableClicked(object sender, EventArgs e)
        {
            mon.Disable();
            Update(mon.Count);
            RefreshNotifierState();
        }

        void Notifier_ExitClicked(object sender, EventArgs e)
        {
            this.ExitThread();
        }

        private void Update(int number)
        {
            notifier.Text = "Running TypeScript compilers: " + number.ToString();
            UpdateIcon(number);
        }

        private void UpdateIcon(int number)
        {
            notifier.Icon = 
                mon.Enabled ? number < NUMBER_LIMIT ? icons[number] : icons[NUMBER_LIMIT]
                : icons[NUMBER_LIMIT + 1];
        }

        private void RefreshNotifierState()
        {
            notifier.ContextMenu.MenuItems[0].Enabled = !mon.Enabled;
            notifier.ContextMenu.MenuItems[1].Enabled = mon.Enabled;
        }

        protected override void Dispose(bool disposing)
        {
            notifier.Visible = false;
            base.Dispose(disposing);
        }
    }
}
